'''
Created on 04/08/2009

@author: eh01
'''
#from datastore.database import DataStore
#from datastore.resource import Resource
from runtime import boot
from runtime.boot import XMLFormatException, BadYarraPackageException,\
    MetaFinder, MetaLoader
from xml.etree import ElementTree
from zipfile import ZipFile
#from datastore import database
from datastore import *
import base64
import imp
import os
import sys
import unittest
import hashlib


class BootTest(unittest.TestCase):


    def setUp(self):
        pass


    def tearDown(self):
        try: os.remove('node.db3')
        except: pass
        try: os.remove('test.yarra')
        except: pass
        try: os.remove('test1.yarra')
        except: pass
        try: os.remove('test2.yarra')
        except: pass
        try: os.remove('test_distribution.xml')
        except: pass
    
    def test_download_file_case_1(self):
        '''[boot] test download file file exists'''
        try:
            test_file_content = "Hello. This is\na test of a file to\nbe read."
            cur_dir = os.getcwd()
            path_to_file = cur_dir + '\\test.file'
            file1 = open(path_to_file, "wb")
            file1.write(test_file_content)
            file1.close()
            url = 'file:///{0}'.format(path_to_file)
            file2 = boot.download_file(url)
            content_as_string = file2.read()
            file2.close()
            if test_file_content == content_as_string:
                assert True
            else:
                self.fail('download failed')
        finally:
            os.remove(path_to_file)

    def test_download_file_case_2(self):
        '''[boot] test download file file doesnt exists'''
        cur_dir = os.getcwd()
        path_to_file = cur_dir + '\\test.file'
        url = 'file:///{0}'.format(path_to_file)
        try:
            file = boot.download_file(url)
            self.fail('should not be able to find file')
        except IOError:
            assert True
    
    def test_get_zip_content_case_1(self):
        '''[boot] test get zip content with correctly serialised resources'''
        test_string = "HELLO WORLD"
        file_name = 'testfile'
        zip_file_name = 'test.zip'
        encoded_test_string = base64.encodestring(test_string)
        xml_string = '<?xml version="1.0" encoding="UTF-8" ?><root><content><item>{0}</item></content></root>'.format(encoded_test_string)
        zip1 = ZipFile(zip_file_name, 'w')
        zip1.writestr(file_name, xml_string)
        zip1.close()
        zip1 = None
        zip2 = ZipFile(zip_file_name, 'r')
        self.assertEqual( test_string, boot.get_zip_content(zip2, file_name))
        zip2.close()
        zip2 = None
        os.remove(zip_file_name)
        
    def test_get_zip_content_case_2(self):
        '''[boot] test get zip content with incorrectly serialised resources'''
        test_string = "HELLO WORLD"
        file_name = 'testfile'
        zip_file_name = 'test.zip'
        encoded_test_string = base64.encodestring(test_string)        
        xml_string = '<?xml version="1.0" encoding="UTF-8" ?><root><blahtag><item>{0}</item></blahtag></root>'.format(encoded_test_string)
#        xml_string = '<?xml version="1.0" encoding="UTF-8" ?><root xmlns="http://yarra-project.com/element/"><content><item>{0}</item></content></root>'.format(encoded_test_string)
        zip1 = ZipFile(zip_file_name, 'w')
        zip1.writestr(file_name, xml_string)
        zip1.close()
        zip1 = None
        zip2 = ZipFile(zip_file_name, 'r')
        try:
            bzc = boot.get_zip_content(zip2, file_name)
            self.assertEqual(test_string, bzc)
            self.fail('Content should not be successfully extracted')
        except XMLFormatException:
            assert True
        finally:
            zip2.close()
            zip2 = None
            os.remove(zip_file_name)
    
    def test_is_first_time_case_1(self):
        '''[boot] test is first time for first time '''
        # change the database name so it doesn't pick up the current db file in the folder
        temp_database_name = 'testnode.db3'
        original_database_name = boot.DATABASE_NAME
        database.DATABASE_NAME = temp_database_name        
        boot.DATABASE_NAME = temp_database_name
        
        self.assertTrue(boot.is_first_time())
        
        # restore
        boot.DATABASE_NAME = original_database_name
        database.DATABASE_NAME = original_database_name
        
        
        
    def test_is_first_time_case_2(self):
        '''[boot] test is first time for not first time '''
        # change the database name so it doesn't pick up the current db file in the folder
        boot.DATABASE_NAME = 'testnode.db3'
        
        # create a temp database file, to make it look like the software has been run before
        file = open(boot.DATABASE_NAME, "w")
        file.close()
        
        self.assertFalse(boot.is_first_time())
        
        # remove the temp database file
        os.remove(boot.DATABASE_NAME)
    
    def test_get_startup_module_names_case_1(self):
        '''[boot] test get startup module names with a syntactically correct configuration'''
        xml_string = '''<?xml version="1.0" encoding="UTF-8" ?>
        <resource>
            <content>
                <list key="package:manifest/modules">
                    <dict>
                        <item key="package:filename" type="yarra:type/string">module1.py</item>
                        <item key="package:startup" type="yarra:type/boolean">True</item>
                    </dict>
                    <dict>
                        <item key="package:filename" type="yarra:type/string">module2.py</item>
                        <item key="package:startup" type="yarra:type/boolean">False</item>
                    </dict>
                    <dict>
                        <item key="package:filename" type="yarra:type/string">module3.py</item>
                        <item key="package:startup" type="yarra:type/boolean">True</item>
                    </dict>                                                 
                </list>
            </content>
        </resource>'''           
                
        configuration_xml_root_element = ElementTree.XML(xml_string)
        self.assertEqual(['module1.py', 'module3.py'], boot.get_startup_module_names(configuration_xml_root_element))
        
    def test_get_startup_module_names_case_2(self):
        '''[boot] test get startup module names with a syntactically correct configuration but no modules'''
        xml_string = '''<?xml version="1.0" encoding="UTF-8" ?>
        <resource>
            <content>
                <list key="package:manifest/modules">                         
                </list>
            </content>
        </resource>''' 
        
        configuration_xml_root_element = ElementTree.XML(xml_string)
        self.assertEqual([], boot.get_startup_module_names(configuration_xml_root_element))        

    def test_get_startup_module_names_case_3(self):
        '''[boot] test get startup module names with a syntactically incorrect configuration'''
        xml_string = '''<?xml version="1.0" encoding="UTF-8" ?>
        <resource>
            <blahtag>
                <list key="package:manifest/modules">
                    <dict>
                        <item key="package:filename" type="yarra:type/string">module1.py</item>
                        <item key="package:startup" type="yarra:type/boolean">True</item>
                    </dict>
                    <dict>
                        <item key="package:filename" type="yarra:type/string">module2.py</item>
                        <item key="package:startup" type="yarra:type/boolean">False</item>
                    </dict>
                    <dict>
                        <item key="package:filename" type="yarra:type/string">module3.py</item>
                        <item key="package:startup" type="yarra:type/boolean">True</item>
                    </dict>                                                 
                </list>
            </blahtag>
        </resource>'''  
        
        configuration_xml_root_element = ElementTree.XML(xml_string)
        
        try:
            boot.get_startup_module_names(configuration_xml_root_element)
            self.fail('Should not be able to parse the xml')
        except XMLFormatException:
            assert True      

    def test_get_startup_modules_content_case_1(self):
        '''[boot] test get startup modules content of package with yarra package'''
        # create test data
        zip_file_name = 'test.zip'
        configuration_file_name = 'configuration.xml'
        module1_file_name = 'module1.py'
        module2_file_name = 'module2.py'
        module1_contents = "Hello World1"
        module2_contents = "Hello World2"
        configuration_contents = '''<?xml version="1.0" encoding="UTF-8" ?>
        <resource>
            <content>
                <list key="package:manifest/modules">
                    <dict>
                        <item key="package:filename" type="yarra:type/string">module1.py</item>
                        <item key="package:startup" type="yarra:type/boolean">True</item>
                    </dict>
                    <dict>
                        <item key="package:filename" type="yarra:type/string">module2.py</item>
                        <item key="package:startup" type="yarra:type/boolean">False</item>
                    </dict>                                                 
                </list>
            </content>
        </resource>''' 
        xml_resource_template = '<?xml version="1.0" encoding="UTF-8" ?><root><content><item>{0}</item></content></root>'    
        zip1 = ZipFile(zip_file_name, 'w')
        zip1.writestr(configuration_file_name, configuration_contents)
        zip1.writestr(module1_file_name + ".xml", xml_resource_template.format(base64.encodestring(module1_contents)))
        zip1.writestr(module2_file_name + ".xml", xml_resource_template.format(base64.encodestring(module2_contents)))
        zip1.close()
        zip1 = None
        file = open(zip_file_name, 'rb')
        content = file.read()
        file.close()
        file = None
        zip1_hash = "SHA1:%s" % hashlib.sha1(content).hexdigest()
 
        # get contents  
        contents = boot.get_startup_modules_content(zip_file_name, zip1_hash)
        print contents
        self.assertFalse((configuration_file_name, configuration_contents) in contents)
        self.assertTrue((module1_file_name, module1_contents) in contents)
        self.assertFalse((module2_file_name, module2_contents) in contents)
        os.remove(zip_file_name)
        
    def test_get_startup_modules_content_case_2(self):
        '''[boot] test get startup modules content of package with a bad yarra package file'''
        
        # create bad test data. Yarra package should be a zip file
        zip_file_name = 'test.zip'
        file1 = open(zip_file_name, "wb")
        file1.close()
        file1 = None
        file = open(zip_file_name, 'rb')
        content = file.read()
        file.close()
        file = None
        zip1_hash = "SHA1:%s" % hashlib.sha1(content).hexdigest()
          
        try:
            # get contents
            boot.get_startup_modules_content(zip_file_name, zip1_hash)
            self.fail('Yarra package should not be parsed successfully')
        except BadYarraPackageException:
            assert True    
            
        os.remove(zip_file_name)
            
    def test_get_startup_modules_content_case_3(self):
        '''[boot] test get startup modules content of package with bad yarra package'''
        # create test data
        zip_file_name = 'test.zip'
        module1_file_name = 'module1.py'
        module2_file_name = 'module2.py'
        module1_contents = "Hello World1"
        module2_contents = "Hello World2"
        xml_resource_template = '<?xml version="1.0" encoding="UTF-8" ?><root xmlns="http://yarra-project.com/element/"><content><item>{0}</item></content></root>'    
        zip1 = ZipFile(zip_file_name, 'w')
        zip1.writestr(module1_file_name + ".xml", xml_resource_template.format(base64.encodestring(module1_contents)))
        zip1.writestr(module2_file_name + ".xml", xml_resource_template.format(base64.encodestring(module2_contents)))
        zip1.close()    
        zip1 = None
        file = open(zip_file_name, 'rb')
        content = file.read()
        file.close()
        file = None
        zip1_hash = "SHA1:%s" % hashlib.sha1(content).hexdigest()
        
        try:
            # get contents  
            dict = boot.get_startup_modules_content(zip_file_name, zip1_hash)
            self.fail('Yarra package should not be parsed successfully')            
        except BadYarraPackageException:
            assert True
        except SystemExit:
            assert True
        os.remove(zip_file_name)
        
    def test_get_startup_modules_content_case_4(self):
        '''[boot] test get startup modules content of package with bad yarra package (wrong algorithm)'''
        # create test data
        zip_file_name = 'test.zip'
        module1_file_name = 'module1.py'
        module2_file_name = 'module2.py'
        module1_contents = "Hello World1"
        module2_contents = "Hello World2"
        xml_resource_template = '<?xml version="1.0" encoding="UTF-8" ?><root xmlns="http://yarra-project.com/element/"><content><item>{0}</item></content></root>'    
        zip1 = ZipFile(zip_file_name, 'w')
        zip1.writestr(module1_file_name + ".xml", xml_resource_template.format(base64.encodestring(module1_contents)))
        zip1.writestr(module2_file_name + ".xml", xml_resource_template.format(base64.encodestring(module2_contents)))
        zip1.close()    
        zip1 = None
        file = open(zip_file_name, 'rb')
        content = file.read()
        file.close()
        file = None
        zip1_hash = "BLAH:%s" % hashlib.sha1(content).hexdigest()
        
        try:
            # get contents  
            dict = boot.get_startup_modules_content(zip_file_name, zip1_hash)
            self.fail('Yarra package should not be parsed successfully')            
        except BadYarraPackageException:
            assert True
        except SystemExit:
            assert True
        os.remove(zip_file_name)        
            
    def test_load_package_case_1(self):
        '''[boot] test load package loading both modules'''
        module1_file_name = 'module1.py'
        module2_file_name = 'module2.py'
        module1_contents = """class TestClassA(object):
    test_attrib_1 = 2"""
        module2_contents = """class TestClassB(object):
    test_attrib_1 = 'blah'"""
        package_contents = [(module1_file_name,module1_contents), (module2_file_name, module2_contents)]
        boot.load_package('testpackage', package_contents)
        
        # import TestClassA
        import_class = 'from testpackage.module1 import TestClassA'
        # create TestClassA
        create_class = 'tcA = TestClassA()'
        # test the attribute
        test = 'self.assertEqual(tcA.test_attrib_1, 2)'
        exec import_class
        exec create_class
        exec test
        
        # import TestClassB
        import_class = 'from testpackage.module2 import TestClassB'
        # create TestClassB
        create_class = 'tcB = TestClassB()'
        # test the attribute
        test = 'self.assertEqual(tcB.test_attrib_1, "blah")'
        exec import_class
        exec create_class
        exec test
        
        # remove the modules from being looked up by imports
        del sys.modules['testpackage']
        del sys.modules['testpackage.module1']        
        del sys.modules['testpackage.module2']

    def test_load_distribution_case_1(self):
        '''[boot] test load distribution loading 2 modules '''
        # create test data
        zip_file_name = 'test.yarra'
        module1_name = 'moduleone'
        module2_name = 'moduletwo'
        module1_file_name = module1_name + '.py'
        module2_file_name = module2_name + '.py'
        module1_contents = """class TestClassA(object):
    test_attrib_1 = 2"""
        module2_contents = """class TestClassB(object):
    test_attrib_1 = 'blah'"""
        distribution_name = "test_distribution"
        distribution_file_name = distribution_name + ".xml"
        configuration_file_name = 'configuration.xml'
        configuration_content = '''<?xml version="1.0" encoding="UTF-8" ?>
        <resource>
            <content>
                <list key="package:manifest/modules">
                    <dict>
                        <item key="package:filename" type="yarra:type/string">{0}</item>
                        <item key="package:startup" type="yarra:type/boolean">True</item>
                    </dict>
                    <dict>
                        <item key="package:filename" type="yarra:type/string">{1}</item>
                        <item key="package:startup" type="yarra:type/boolean">True</item>
                    </dict>                                                 
                </list>
            </content>
        </resource>'''.format(module1_file_name, module2_file_name)
        xml_resource_template = '<?xml version="1.0" encoding="UTF-8" ?><root><content><item>{0}</item></content></root>'        
        zip1 = ZipFile(zip_file_name, 'w')
        zip1.writestr(configuration_file_name, configuration_content)
        zip1.writestr(module1_file_name + ".xml", xml_resource_template.format(base64.encodestring(module1_contents)))
        zip1.writestr(module2_file_name + ".xml", xml_resource_template.format(base64.encodestring(module2_contents)))
        zip1.close()
        zip1 = None
        file = open(zip_file_name, 'rb')
        content = file.read()
        file.close()
        file = None
        zip1_hash = "SHA1:%s" % hashlib.sha1(content).hexdigest()
        package_name = "testpackage"

        distribution_xml = '''<?xml version="1.0" encoding="UTF-8"?>
            <distribution xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://yarra-project.com/element/ distribution.xsd">
                <name>default</name>
                <package>
                    <name>{0}</name>
                    <digest>{1}</digest>
                    <location>{2}</location>
                    <boot>True</boot>            
                </package>
            </distribution>'''.format(package_name, zip1_hash, 'file:///{0}/{1}'.format(os.getcwd(), zip_file_name))
        file = open(distribution_file_name, 'w')
        file.write(distribution_xml)
        file.close()
        file = None
        
        boot.load_distribution('file:///{0}/'.format(os.getcwd()), distribution_name)
        
        os.remove(zip_file_name)
        os.remove(distribution_file_name)
        
        # test the modules have been loaded
        if sys.modules[package_name]:
            module1 = sys.modules["{0}.{1}".format(package_name, module1_name)]
            module2 = sys.modules["{0}.{1}".format(package_name, module2_name)]
            tcA = module1.TestClassA()
            tcB = module2.TestClassB()
            self.assertEqual(tcA.test_attrib_1, 2)
            self.assertEqual(tcB.test_attrib_1, 'blah')
        else:
            self.fail('Modules should have been loaded')

        # remove the modules from being looked up by imports
        del sys.modules[package_name]
        del sys.modules["{0}.{1}".format(package_name, module1_name)]        
        del sys.modules["{0}.{1}".format(package_name, module2_name)]
        
    def test_load_distribution_case_2(self):
        '''[boot] test load distribution loading one module only '''
        # create test data
        zip_file_name1 = 'test1.yarra'
        zip_file_name2 = 'test2.yarra'
        module1_name = 'moduleone'
        module2_name = 'moduletwo'
        module1_file_name = module1_name + '.py'
        module2_file_name = module2_name + '.py'
        module1_contents = """class TestClassA(object):
    test_attrib_1 = 2"""
        module2_contents = """class TestClassB(object):
    test_attrib_1 = 'blah'"""
        package_name_1 = "testpackage1"
        package_name_2 = "testpackage2"
        distribution_name = "test_distribution"
        distribution_file_name = distribution_name + ".xml"
        configuration_file_name = 'configuration.xml'
        configuration1_content = '''<?xml version="1.0" encoding="UTF-8" ?>
        <resource>
            <content>
                <list key="package:manifest/modules">
                    <dict>
                        <item key="package:filename" type="yarra:type/string">{0}</item>
                        <item key="package:startup" type="yarra:type/boolean">True</item>
                    </dict>         
                </list>
            </content>
        </resource>'''.format(module1_file_name)     
        configuration2_content = '''<?xml version="1.0" encoding="UTF-8" ?>
        <resource>
            <content>
                <list key="package:manifest/modules">
                    <dict>
                        <item key="package:filename" type="yarra:type/string">{0}</item>
                        <item key="package:startup" type="yarra:type/boolean">True</item>
                    </dict>                           
                </list>
            </content>
        </resource>'''.format(module2_file_name)        
        xml_resource_template = '<?xml version="1.0" encoding="UTF-8" ?><root><content><item>{0}</item></content></root>'        
        zip1 = ZipFile(zip_file_name1, 'w')
        zip1.writestr(configuration_file_name, configuration1_content)
        zip1.writestr(module1_file_name + ".xml", xml_resource_template.format(base64.encodestring(module1_contents)))
        zip1.close()
        zip1 = None
        file = open(zip_file_name1, 'rb')
        content = file.read()
        file.close()
        file = None
        zip1_hash = "SHA1:%s" % hashlib.sha1(content).hexdigest()
  
        zip2 = ZipFile(zip_file_name2, 'w')
        zip2.writestr(configuration_file_name, configuration2_content)
        zip2.writestr(module2_file_name + ".xml", xml_resource_template.format(base64.encodestring(module2_contents)))
        zip2.close()
        zip2 = None
        file = open(zip_file_name2, 'rb')
        content = file.read()
        file.close()
        file = None
        zip2_hash = "SHA1:%s" % hashlib.sha1(content).hexdigest()     

        distribution_xml = '''<?xml version="1.0" encoding="UTF-8"?>
            <distribution xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://yarra-project.com/element/ distribution.xsd">
                <name>default</name>
                <package>
                    <name>{0}</name>
                    <digest>{1}</digest>
                    <location>{2}</location>
                    <boot>True</boot>            
                </package>
                <package>
                    <name>{3}</name>
                    <digest>{4}</digest>
                    <location>{5}</location>
                    <boot>False</boot>            
                </package>
            </distribution>'''.format(package_name_1, zip1_hash, 'file:///{0}/{1}'.format(os.getcwd(), zip_file_name1), 
                          package_name_2, zip2_hash, 'file:///{0}/{1}'.format(os.getcwd(), zip_file_name2))
        file = open(distribution_file_name, 'w')
        file.write(distribution_xml)
        file.close()
        file = None
        
        boot.load_distribution('file:///{0}/'.format(os.getcwd()), distribution_name, True)
        
        os.remove(zip_file_name1)
        os.remove(zip_file_name2)
        os.remove(distribution_file_name)
        
        # test the modules have been loaded
        if sys.modules[package_name_1]:
            module1 = sys.modules["{0}.{1}".format(package_name_1, module1_name)]
            tcA = module1.TestClassA()
            self.assertEqual(tcA.test_attrib_1, 2)
        else:
            self.fail('Module should have been loaded')            
        if package_name_2 in sys.modules:
            self.fail('Should have not loaded this module')            

        # remove the modules from being looked up by imports
        del sys.modules["{0}.{1}".format(package_name_1, module1_name)]
        
    def test_get_rt_module_case_1(self):
        '''[boot] test get rt module when rt module exists'''
        package = imp.new_module(boot.RUNTIME_PACKAGE_NAME)
        module = imp.new_module(boot.RUNTIME_MODULE_PATH)    
        sys.modules[boot.RUNTIME_PACKAGE_NAME] = package
        sys.modules[boot.RUNTIME_MODULE_PATH] = module         
        rt_module = boot.get_rt_module()
        self.assertEqual(module, rt_module)
        del sys.modules[boot.RUNTIME_MODULE_PATH]
        del sys.modules[boot.RUNTIME_PACKAGE_NAME]

    def test_get_rt_module_case_2(self):
        '''[boot] test get rt module when rt module doesnt exists'''
        try:    
            boot.get_rt_module()
            self.fail('should have failed')
        except Exception:
            assert True
    
    def test_first_time_case_1(self):
        '''[boot] test first time''' 
        # create test data
        zip_file_name = 'test.yarra'
        module1_name = 'moduleone'
        module2_name = 'moduletwo'
        module1_file_name = module1_name + '.py'
        module2_file_name = module2_name + '.py'
        module1_contents = """class TestClassA(object):
    test_attrib_1 = 2"""
        module2_contents = """class TestClassB(object):
    test_attrib_1 = 'blah'"""
        package_name = "testpackage"
        configuration_file_name = 'configuration.xml'
        configuration_content = '''<?xml version="1.0" encoding="UTF-8" ?>
        <resource>
            <content>
                <list key="package:manifest/modules">
                    <dict>
                        <item key="package:filename" type="yarra:type/string">{0}</item>
                        <item key="package:startup" type="yarra:type/boolean">True</item>
                    </dict>
                    <dict>
                        <item key="package:filename" type="yarra:type/string">{1}</item>
                        <item key="package:startup" type="yarra:type/boolean">True</item>
                    </dict>                                                 
                </list>
            </content>
        </resource>'''.format(module1_file_name, module2_file_name)        
        xml_resource_template = '<?xml version="1.0" encoding="UTF-8" ?><root><content><item>{0}</item></content></root>'        
        zip1 = ZipFile(zip_file_name, 'w')
        zip1.writestr(configuration_file_name, configuration_content)
        zip1.writestr(module1_file_name + ".xml", xml_resource_template.format(base64.encodestring(module1_contents)))
        zip1.writestr(module2_file_name + ".xml", xml_resource_template.format(base64.encodestring(module2_contents)))
        zip1.close()
        zip1 = None
        file = open(zip_file_name, 'rb')
        content = file.read()
        file.close()
        file = None
        zip1_hash = "SHA1:%s" % hashlib.sha1(content).hexdigest()
        
        distribution_name = "test_distribution"
        distribution_file_name = distribution_name + ".xml"
        distribution_xml = '''<?xml version="1.0" encoding="UTF-8"?>
        <distribution xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://yarra-project.com/element/ distribution.xsd">
            <name>default</name>
            <package>
                <name>{0}</name>
                <digest>{1}</digest>
                <location>{2}</location>
                <boot>True</boot>           
            </package>
        </distribution>'''.format(package_name, zip1_hash, 'file:///{0}/{1}'.format(os.getcwd(), zip_file_name))
        file = open(distribution_file_name, 'w')
        file.write(distribution_xml)
        file.close()
        file = None
                
        boot.first_time('file:///{0}/'.format(os.getcwd()), distribution_name)
        
        os.remove(zip_file_name)
        os.remove(distribution_file_name)
        
        # test the modules have been loaded
        if package_name in sys.modules:
            module1 = sys.modules["{0}.{1}".format(package_name, module1_name)]
            module2 = sys.modules["{0}.{1}".format(package_name, module2_name)]
            tcA = module1.TestClassA()
            tcB = module2.TestClassB()
            self.assertEqual(tcA.test_attrib_1, 2)
            self.assertEqual(tcB.test_attrib_1, 'blah')
        else:
            self.fail('Modules should have been loaded')

        # remove the modules from being looked up by imports
        del sys.modules[package_name]
        del sys.modules["{0}.{1}".format(package_name, module1_name)]        
        del sys.modules["{0}.{1}".format(package_name, module2_name)]     


class MetaFinderTest(unittest.TestCase):
    
    def test_find_module_case_1(self):
        '''[boot] test find module where module is not found in datastore'''
        temp_database_name = 'test.db'
        original_database_name = boot.DATABASE_NAME
        boot.DATABASE_NAME = temp_database_name
        database.DATABASE_NAME = temp_database_name
        database.DataStore()             
        mf = MetaFinder()
        self.assertEqual(None, mf.find_module('blah'))
        database.DATABASE_NAME = original_database_name
        boot.DATABASE_NAME = original_database_name
        os.remove(temp_database_name)

    def test_find_module_case_2(self):
        '''[boot] test find module where module is found in datastore and module is a package'''
        package_name = 'testpackage'
        temp_database_name = 'test.db'
        original_database_name = boot.DATABASE_NAME
        boot.DATABASE_NAME = temp_database_name
        database.DATABASE_NAME = temp_database_name
        ds = database.DataStore()
        rs = resource.Resource()
        rs.set_metadata(Uri(boot.METADATA_PACKAGE_NAME), package_name)
        ds.put([rs])
        mf = MetaFinder()
        self.assertEqual(mf.find_module(package_name), MetaLoader(1, Uri(boot.METADATA_PACKAGE_NAME)))
        database.DATABASE_NAME = original_database_name
        boot.DATABASE_NAME = original_database_name
        os.remove(temp_database_name)
        
    def test_find_module_case_3(self):
        '''[boot] test find module where module is found in datastore and module is a module'''
        module_path = 'testpackage.testmodule'
        temp_database_name = 'test.db'
        original_database_name = boot.DATABASE_NAME
        boot.DATABASE_NAME = temp_database_name
        database.DATABASE_NAME = temp_database_name
        ds = database.DataStore()
        rs = resource.Resource()
        rs.set_metadata(Uri(boot.METADATA_MODULE_NAME), module_path)
        ds.put([rs])
        mf = MetaFinder()
        self.assertEqual(mf.find_module(module_path), MetaLoader(1, Uri(boot.METADATA_MODULE_NAME)))
        database.DATABASE_NAME = original_database_name
        boot.DATABASE_NAME = original_database_name
        os.remove(temp_database_name)
        
class MetaLoaderTest(unittest.TestCase):
    
    def test_load_module_case_1(self):
        '''[boot] test load module where module is a package'''
        package_name = 'testpackage'
        temp_database_name = 'test.db'        
        original_database_name = boot.DATABASE_NAME
        boot.DATABASE_NAME = temp_database_name
        database.DATABASE_NAME = temp_database_name
        ds = database.DataStore()
        rs = resource.Resource()
        rs.set_metadata(Uri(boot.METADATA_PACKAGE_NAME), package_name)
        ds.put([rs])
        mt = MetaLoader(1, Uri(boot.METADATA_PACKAGE_NAME))
        self.assertTrue(mt.load_module(package_name) != None and sys.modules[package_name])
        database.DATABASE_NAME = original_database_name
        boot.DATABASE_NAME = original_database_name
        os.remove(temp_database_name)
        del sys.modules[package_name]
        
    def test_load_module_case_2(self):
        '''[boot] test load module where module is a module'''
        package_name = 'testpackage'
        module_path = '{0}.testmodule'.format(package_name)
        temp_database_name = 'test.db'        
        original_database_name = boot.DATABASE_NAME
        boot.DATABASE_NAME = temp_database_name
        database.DATABASE_NAME = temp_database_name
        boot.create_module(package_name)
        ds = database.DataStore()
        rs = resource.Resource()
        rs.content = """class TestClassA(object):
    test_attrib_1 = 2"""        
        rs.set_metadata(Uri(boot.METADATA_MODULE_NAME), module_path)
        ds.put([rs])
        mt = MetaLoader(1, Uri(boot.METADATA_MODULE_NAME))
        self.assertTrue(mt.load_module(module_path) != None and sys.modules[module_path])
        m = sys.modules[module_path]
        tca = m.TestClassA()
        self.assertTrue(tca.test_attrib_1 == 2)
        database.DATABASE_NAME = original_database_name
        boot.DATABASE_NAME = original_database_name
        os.remove(temp_database_name)  
        del sys.modules[package_name]
        del sys.modules[module_path]      

    def test_load_module_case_3(self):
        '''[boot] test load module where module is a module and the module exists already'''
        package_name = 'testpackage'
        module_path = '{0}.testmodule'.format(package_name)
        temp_database_name = 'test.db'        
        original_database_name = boot.DATABASE_NAME
        boot.DATABASE_NAME = temp_database_name
        database.DATABASE_NAME = temp_database_name
        boot.create_module(package_name)
        boot.create_module(module_path)
        ds = database.DataStore()
        rs = resource.Resource()
        rs.content = """class TestClassA(object):
    test_attrib_1 = 2"""        
        rs.set_metadata(Uri(boot.METADATA_MODULE_NAME), module_path)
        ds.put([rs])
        mt = MetaLoader(1, Uri(boot.METADATA_MODULE_NAME))
        self.assertTrue(mt.load_module(module_path) != None and sys.modules[module_path])
        m = sys.modules[module_path]
        tca = m.TestClassA()
        self.assertTrue(tca.test_attrib_1 == 2)
        database.DATABASE_NAME = original_database_name
        boot.DATABASE_NAME = original_database_name
        os.remove(temp_database_name)  
        del sys.modules[package_name]
        del sys.modules[module_path] 
        
if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testName']
    unittest.main()